/*
Program Name
Copyright (C) 2008 Matthew Perry

This library is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.

This libary/program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

using System;

namespace BaseTools.Strings
{
	/// <summary>
	/// An escape sequence
	/// </summary>
	public struct EscapeSequence : IEquatable<EscapeSequence>
	{
		/// <summary>
		/// Character that invokes the sequence
		/// </summary>
		public char Sequence;
		
		/// <summary>
		/// Character created by the sequence
		/// </summary>
		public char Output;
		
		/// <summary>
		/// Create an escape sequence
		/// </summary>
		/// <param name="Sequence">Character that invokes the sequence</param>
		/// <param name="Output">Character created by the sequence</param>
		public EscapeSequence(char Sequence, char Output)
		{
			this.Sequence = Sequence;
			this.Output = Output;
		}
		
		/// <summary>
		/// Finds the first sequence with the specified sequence
		/// </summary>
		/// <param name="list">The list of sequences</param>
		/// <param name="sequence">The sequence to search for</param>
		/// <returns>The index of the first matching sequence or -1 if not found</returns>
		public static int FindBySequence(EscapeSequence[] list, char sequence)
		{
			for(int i=0;i<list.Length;i++)
			{
				if (list[i].Sequence == sequence)
					return i;
			}
			return -1;
		}
		
		/// <summary>
		/// Finds the first sequence with the specified output
		/// </summary>
		/// <param name="list">The list of sequences</param>
		/// <param name="output">The output to search for</param>
		/// <returns>The index of the first matching sequence or -1 if not found</returns>
		public static int FindByOutput(EscapeSequence[] list, char output)
		{
			for(int i=0;i<list.Length;i++)
			{
				if (list[i].Output == output)
					return i;
			}
			return -1;
		}
		
		#region Equals and GetHashCode implementation
		// The code in this region is useful if you want to use this structure in collections.
		// If you don't need it, you can just remove the region and the ": IEquatable<EscapeSequence>" declaration.
		
		/// <summary>
		/// Compares an escape sequence
		/// </summary>
		/// <param name="obj">The escape sequence to compare to</param>
		/// <returns></returns>
		public override bool Equals(object obj)
		{
			if (obj is EscapeSequence)
				return Equals((EscapeSequence)obj); // use Equals method below
			else
				return false;
		}
		
		/// <summary>
		/// Compares an escape sequence
		/// </summary>
		/// <param name="other">The escape sequence to compare to</param>
		/// <returns></returns>
		public bool Equals(EscapeSequence other)
		{
			// add comparisions for all members here
			return this.Sequence == other.Sequence && this.Output == other.Output;
		}
		
		/// <summary>
		/// Generates a hash code
		/// </summary>
		/// <returns>The hash code</returns>
		public override int GetHashCode()
		{
			// combine the hash codes of all members here (e.g. with XOR operator ^)
			return Sequence.GetHashCode() ^ Output.GetHashCode();
		}
		
		/// <summary>
		/// Compares
		/// </summary>
		/// <param name="lhs"></param>
		/// <param name="rhs"></param>
		/// <returns></returns>
		public static bool operator ==(EscapeSequence lhs, EscapeSequence rhs)
		{
			return lhs.Equals(rhs);
		}
		
		/// <summary>
		/// Not compares
		/// </summary>
		/// <param name="lhs"></param>
		/// <param name="rhs"></param>
		/// <returns></returns>
		public static bool operator !=(EscapeSequence lhs, EscapeSequence rhs)
		{
			return !(lhs.Equals(rhs)); // use operator == and negate result
		}
		#endregion
	}
}
